package com.huan.social.qq.api.impl;

import com.google.gson.Gson;
import com.huan.social.qq.api.Qq;
import com.huan.social.qq.api.QqUserInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.social.oauth2.AbstractOAuth2ApiBinding;
import org.springframework.social.oauth2.TokenStrategy;
import org.springframework.web.client.RestTemplate;

import java.nio.charset.StandardCharsets;

/**
 * QQ 接口实现，用于调用QQ服务的一些信息，如果获取用户信息
 * author : huan.fu
 * Created by huan on 2018/09/24.
 */
@Slf4j
public class QqTemplate extends AbstractOAuth2ApiBinding implements Qq {

	/**
	 * 在 QQ 互联上申请应用分配的 id
	 */
	private String appId;
	/**
	 * 用户的 open_id
	 */
	private String openId;
	/**
	 * 获取 open_id 的 url
	 */
	private String openIdUrl;
	/**
	 * 获取QQ用户信息的url
	 */
	private String userInfoUrl;

	public QqTemplate(String appId, String accessToken, String openIdUrl, String userInfoUrl) {
		/**
		 * 调用父类 2 个参数的构造方法，
		 * TokenStrategy.ACCESS_TOKEN_PARAMETER表示父类将会自动处理 access_token 这个参数
		 */
		super(accessToken, TokenStrategy.ACCESS_TOKEN_PARAMETER);
		this.appId = appId;
		this.openIdUrl = openIdUrl;
		this.userInfoUrl = userInfoUrl;
		this.openId = this.getOpenId(accessToken);
	}

	/**
	 * 获取用户的 openId
	 *
	 * @return 返回用户的openId
	 */
	private String getOpenId(String accessToken) {
		String result = getRestTemplate().getForObject(String.format(openIdUrl, accessToken), String.class);
		log.info("获取openId结果:[{}]", result);
		return StringUtils.substringBetween(result, "\"openId\":\"", "\"}");
	}

	/**
	 * 获取 QQ 用户的信息
	 *
	 * @return
	 */
	@Override
	public QqUserInfo getQqUserInfo() {
		return new Gson()
				.fromJson(getRestTemplate().getForObject(String.format(this.userInfoUrl, appId, openId), String.class), QqUserInfo.class);
	}

	@Override
	public String getOpenId() {
		return this.openId;
	}

	/**
	 * 防止返回值乱码
	 *
	 * @param restTemplate
	 */
	@Override
	protected void configureRestTemplate(RestTemplate restTemplate) {
		restTemplate.getMessageConverters().forEach(convert -> {
			if (convert instanceof StringHttpMessageConverter) {
				((StringHttpMessageConverter) convert).setDefaultCharset(StandardCharsets.UTF_8);
			}
		});
	}
}
